package com.example.mq.mqsever.core;

import java.io.Serializable;
import java.util.Arrays;
import java.util.UUID;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-08-20
 * Time: 17:59
 */
//表示一个要传递的消息

/**
 * 此处的Message对象,是需要在网络上进行传输的还要能够写入文件,
 * 就需要针对Message进行序列化和反序列化的操作
 * 我们使用标准库自带的序列化/反序列化操作
 * 需要被序列化的类要实现一个接口,Serializable,这个接口比较特殊,不需要重写任何方法
 */
//一个消息包含属性BasicProperties和正文byte[]两个部分,正文支持二进制数据
public class Message implements Serializable {
    //这个可以写可以不写,它的用途是验证版本的,代码不断更新,如果Message对象变了,那么就会报错
    private static final long serialVersionUID=1L;

     private BasicProperties basicProperties=new BasicProperties();//防止在执行第一个方法的时候为空
     private byte[] body;
     //以上两个属性是message的核心属性,下面介绍辅助属性
    //message会存储到文件中(入过要持久化的话)
    //一个文件可能会存储很多的消息,如何找到某个信息,在文件中的具体位置呢
    //使用下列的两个偏移量来进行表示[offBeg,offEnd)
    //这俩属性不需要被序列化保存到文件中,,此时消息一旦被写入文件中,位置就固定了
    //这俩属性存在的目的,主要是为了让内存中的message对象快速的找到对应的硬盘上message的位置
    //transient表示该属性不能被序列化,是一个特殊的关键字
     private  transient long offsetBeg=0;//消息数据的开头距离文件开头的位置偏移(单位是字节)
     private transient   long offsetEnd=0;//消息数据的结尾距离文件开头的位置偏移(单位是字节)
    //使用这个属性表示该消息是否是有效消息,无效就逻辑删除,这个不算真的删除,而是标记成无效
    //0x1表示有效,0x0表示无效,这是在硬盘或者文件上表示的
     private byte isValid=0x1;
     //创建一个工厂方法,让工厂方法封装一下创建Message对象的方法
    public static Message createMessageWithId(String routingKey,BasicProperties basicProperties,byte[] body){
        Message message=new Message();
        if(basicProperties!=null){
            message.setBasicProperties(basicProperties);
        }
        //此处生成的MessageId以M-作为前缀
        //这里的id做了覆盖
        message.setMessageId("M"+ UUID.randomUUID());
        //将rootingKey也要覆盖
        message.setRootingKey(routingKey);
        //这个body也要覆盖
        message.body=body;
        //此处将body和basicProperties先设置出来,这俩是Message的核心属性,这是在内存创建message对象
        //offsetBeg,offsetEnd,isValid,是消息持久化的时候才会用到,把消息写入文件前再进行设定
        return message;
    }

    public String getMessageId(){
        return basicProperties.getMessageId();
    }
    public void setMessageId(String messageId){
        basicProperties.setMessageId(messageId);
    }
    public String getRootingKey(){
        return basicProperties.getRoutingKey();

    }
     public void setRootingKey(String rootingKey){
        basicProperties.setRoutingKey(rootingKey);
    }
    public int getDeliverMode(){
        return basicProperties.getDeliverMode();
    }
    public void setDeliverMode(int deliverMode){
        basicProperties.setDeliverMode(deliverMode);
    }
    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    public long getOffsetBeg() {
        return offsetBeg;
    }

    public void setOffsetBeg(long offsetBeg) {
        this.offsetBeg = offsetBeg;
    }

    public long getOffsetEnd() {
        return offsetEnd;
    }

    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    public byte getIsValid() {
        return isValid;
    }

    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }

    @Override
    public String toString() {
        return "Message{" +
                "basicProperties=" + basicProperties +
                ", body=" + Arrays.toString(body) +
                '}';
    }

    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    public byte[] getBody() {
        return body;
    }

    public void setBody(byte[] body) {
        this.body = body;
    }
}
